import fs from "fs";
import path from "path";
import fse from "fs-extra";
import { spawn } from "child_process";
import { simpleGit } from "simple-git";

// 执行命令
export function command(
  cmd: string,
  args: string[] = [],
  path: string = process.cwd()
) {
  return new Promise<void>((resolve, reject) => {
    const pro = spawn(cmd, args, { cwd: path, shell: true });
    pro.stdout.pipe(process.stdout);
    pro.stderr.pipe(process.stderr);
    pro.on("error", (err) => {
      reject(new Error(`无法启动进程: ${err.message}`));
    });
    pro.on("close", (code) => {
      if (code === 0) {
        resolve();
      } else {
        reject(new Error(`执行命令失败：退出代码为 ${code}`));
      }
    });
  });
}

// 运行命令
export function runCommand(cmd: string, path: string) {
  const values = cmd.split(/\s/);
  const cwd = values[0];
  const params = values.slice(1);
  return command(cwd, params, path);
}

// git克隆
export function gitClone(url: string, branch = "master", outPath = ".") {
  return command("git", ["clone", "-b", branch, url, outPath]);
}

// git历史
export async function gitLog(
  option: any,
  pageIndex: number = 1,
  pageSize: number = 10
) {
  if (option.maxCount) {
    return simpleGit(option).log();
  } else {
    // 计算需要跳过的提交数量;
    const skipCount = (pageIndex - 1) * pageSize;
    // 构建包含分页选项的 git log 命令
    const logOptions = [
      "--pretty=format:%H - %an, %cd : %s",
      "--date=format:%Y-%m-%d %H:%M:%S",
      `--skip=${skipCount}`,
      `--max-count=${pageSize}`,
    ];
    // 执行 git log 命令
    const log = await simpleGit(option).raw(["log", ...logOptions]);
    // 将结果按行分割成数组
    const commits = log.split("\n");
    return parseGitLog(commits);
  }
}

// 解析 Git 日志
export function parseGitLog(commits: string[]): object[] {
  return commits
    .filter((line) => line.trim())
    .map((line) => {
      // 优化后的正则表达式，支持中文作者名和特殊字符
      const match = line.match(
        /^(\S+) - ([\w\s\u4e00-\u9fa5]+), (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) : (.*)$/
      );

      if (!match) {
        console.warn(`无法解析的日志行: ${line}`);
        return null;
      }

      const [, hash, author, date, message] = match;
      return {
        hash,
        author: author.trim(), // 去除作者名前后空格
        date,
        message,
      };
    })
    .filter(Boolean) as object[];
}

// 部署
export function deployment({
  buildPath,
  deployPath,
  hashPath,
}: API.DeployParams) {
  fs.rmSync(deployPath, { recursive: true, force: true });
  if (fs.existsSync(hashPath)) {
    fse.copySync(hashPath, deployPath);
  } else {
    fse.copySync(buildPath, deployPath);
    fse.copySync(deployPath, hashPath);
  }
}

// 回滚
export async function rollback({ deployPath, hashPath }: API.DeployParams) {
  fs.rmSync(deployPath, { recursive: true, force: true });
  if (fs.existsSync(hashPath)) {
    fse.copySync(hashPath, deployPath);
  } else {
    throw new Error("版本回退失败，不存在该版本的部署代码");
  }
}

// 获取部署参数
export function getDeployParams(row: any, git_commit_id: string) {
  const { build_folder_name, deploy_folder_name, deploy_path, install_path } =
    row;
  const buildPath = path.join(install_path, build_folder_name);
  const deployPath = path.join(deploy_path, deploy_folder_name);
  const hashPath = path.join(deploy_path, git_commit_id);
  return { buildPath, deployPath, hashPath };
}

// 获取安装路径
export function getInstallPath(params: any) {
  if (params.install_path === "project") {
    const relativePath = `/project_${process.env.MODE}/${params.project_name}`;
    return path.join(process.cwd(), relativePath);
  } else {
    return params.install_path;
  }
}

// 获取部署文件夹名
export function getDeployFolderName(params: any) {
  if (!params.deploy_folder_name) {
    return params.project_name;
  } else {
    return params.deploy_folder_name;
  }
}
